home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
ftp.mactech.com 2010
/
ftp.mactech.com.tar
/
ftp.mactech.com
/
challenge
/
12.04-Apr96
/
LifeTestCode DR3.sit
/
Life TestCode DR3
/
LifeFile.c
< prev
next >
Wrap
Text File
|
1996-03-31
|
9KB
|
334 lines
/* LifeFile.c */
/* ©Ludovic Nicolle 1996 */
#include "LifeFile.h"
/*
CreateLifeFile first is a standard save dialog to create
a file of type 'LIFE' and creator 'MULI' .
The file size is set to 4 and the four bytes are set to 0 to
reflect the fact there is originally no LifeRun in the file.
If a file is open, its reference number is placed in refnum
*/
OSErr CreateLifeFile(short *refNum, FSSpec *fileSpec)
{
OSErr iErr = noErr;
Str255 savePrompt = "\pSave LifeFile™ as…";
Str255 saveDefault = "\pUntitled";
StandardFileReply reply;
long ioCount = 4;
long numRuns = 0;
StandardPutFile(savePrompt, saveDefault, &reply);
if (!reply.sfGood)
return userCanceledErr;
if (reply.sfReplacing)
iErr = FSpDelete(&reply.sfFile);
if (iErr)
return iErr;
iErr = FSpCreate(&reply.sfFile, MutantLifeCreator, LifeFileType, smSystemScript);
if (iErr == noErr)
{
iErr = FSpOpenDF(&reply.sfFile, fsCurPerm, refNum);
if (iErr)
{
FSpDelete(&reply.sfFile);/*cannot open file, so delete it*/
return iErr;
}
}
if (refNum != 0) /*paranoïa check!*/
{
iErr = SetFPos(*refNum, fsFromStart, 0);
iErr = FSWrite(*refNum, &ioCount, &numRuns);
}
*fileSpec = reply.sfFile;
return iErr;
}
//#define LifeFileType 'LIFE'
//#define MutantLifeCreator 'MULI'
/*
OpenLifeFile displays the StandardGetFile to open a LifeFile
then open it. if
*/
OSErr OpenLifeFile(short *refNum, FSSpec *fileSpec)
{
OSErr iErr = noErr;
SFTypeList typeList = {'LIFE'};
StandardFileReply reply;
StandardGetFile(nil, 1, typeList, &reply);
if (!reply.sfGood)
return userCanceledErr;
iErr = FSpOpenDF(&reply.sfFile, fsCurPerm, refNum);
*fileSpec = reply.sfFile;
return iErr;
}
OSErr CloseLifeFile(short *refNum)
{
OSErr iErr;
if (*refNum == 0)
return fnOpnErr;
iErr = FSClose(*refNum);
*refNum = 0;
return iErr;
}
OSErr AppendLifeRun(short refNum, LifeRunPtr theRun)
{
OSErr iErr;
long ioCount;
unsigned long numRuns;
long index;
long logEOF;
LifeRun localRun;
long filePos;
if (refNum == 0)
return rfNumErr; /* 0 is invalid file number*/
iErr = GetEOF(refNum, &logEOF);
iErr = SetFPos(refNum, fsFromStart, 0);
ioCount = sizeof(long);
iErr = FSRead(refNum, &ioCount, &numRuns);
if (iErr)
return iErr;
if (numRuns > kMaxRuns)
return tooManyRunsErr;
/* crawl to find logically the end of last run. This should
give the same value as logEOF */
for (index = 0; index < numRuns; index++)
{
ioCount = sizeof(LifeRun);
iErr = FSRead(refNum, &ioCount, &localRun);
if (iErr)
return iErr;
iErr = GetFPos(refNum, &filePos);
filePos += localRun.steps *
(sizeof(long) + /* stepvalue*/
localRun.rbytes *
(localRun.worldSize.bottom - localRun.worldSize.top));
if (filePos > logEOF)
return lifeFileCorruptErr;
iErr = SetFPos(refNum, fsFromStart, filePos);
}
if (iErr == noErr)
{
localRun = *theRun;
localRun.steps = 0; /* initially set to 0 */
ioCount = sizeof(LifeRun);
iErr = FSWrite(refNum, &ioCount, &localRun);
if (iErr == noErr)
{
iErr = SetFPos(refNum, fsFromStart, 0);
numRuns++;
ioCount = sizeof(long);
iErr = FSWrite(refNum, &ioCount, &numRuns);
}
}
return iErr;
}
OSErr SetComputedGen(short refNum, long whichRun, long computedGen)
{
OSErr iErr;
long ioCount;
// unsigned long numRuns;
LifeRun localRun;
long runlength;
long filePos;
iErr = ReadLifeRun(refNum, &localRun, whichRun);
if (iErr)
return iErr;
/* we skipped the entire run with the call to ReadLifeRun
so we rewind the necessary length*/
runlength = localRun.steps *
(sizeof(long) +
localRun.rbytes *
(localRun.worldSize.bottom - localRun.worldSize.top));
iErr = GetFPos(refNum, &filePos);
filePos -= runlength;
filePos -= 20;/*this is the offset from computedGen to the
end of the LifeRun */
iErr = SetFPos(refNum, fsFromStart, filePos);
ioCount = sizeof(long);
iErr = FSWrite(refNum, &ioCount, &computedGen);
return iErr;
}
OSErr AppendLifeWorld(short refNum, BitMapStep *lifeWorld)
{
OSErr iErr;
long ioCount;
unsigned long numRuns;
long index;
long logEOF;
LifeRun localRun;
long filePos;
long runlength;
if (refNum == 0)
return rfNumErr; /* 0 is invalid file number*/
iErr = GetEOF(refNum, &logEOF);
iErr = SetFPos(refNum, fsFromStart, 0);
ioCount = sizeof(long);
iErr = FSRead(refNum, &ioCount, &numRuns);
if (numRuns > kMaxRuns)
return tooManyRunsErr;
if (numRuns == 0)
return noRunsErr;
/* crawl to find logically the end of last run. This should
give the same value as logEOF */
for (index = 0; index < numRuns; index++)
{
ioCount = sizeof(LifeRun);
iErr = FSRead(refNum, &ioCount, &localRun);
if (iErr)
return iErr;
iErr = GetFPos(refNum, &filePos);
runlength = localRun.steps *
(sizeof(long) +
localRun.rbytes *
(localRun.worldSize.bottom - localRun.worldSize.top));
filePos += runlength;
if (filePos > logEOF)
return lifeFileCorruptErr;
iErr = SetFPos(refNum, fsFromStart, filePos);
}
if (iErr)
return iErr;
/* Simple siz checking */
if ((localRun.worldSize.top != lifeWorld->cellsBM.bounds.top) ||
(localRun.worldSize.left != lifeWorld->cellsBM.bounds.left) ||
(localRun.worldSize.bottom != lifeWorld->cellsBM.bounds.bottom) ||
(localRun.worldSize.right != lifeWorld->cellsBM.bounds.right) ||
(localRun.rbytes != lifeWorld->cellsBM.rowBytes))
return badBitMapSizeErr;
/* write the stepvalue */
ioCount = sizeof(long);
iErr = FSWrite(refNum, &ioCount, &lifeWorld->stepvalue);
if (iErr)
return iErr;
ioCount = lifeWorld->cellsBM.rowBytes *
(lifeWorld->cellsBM.bounds.bottom - lifeWorld->cellsBM.bounds.top);
iErr = FSWrite(refNum, &ioCount, lifeWorld->cellsBM.baseAddr);
/* now update the LifeRun structure */
ioCount = sizeof(long);
localRun.steps++;
iErr = SetFPos(refNum, fsFromStart, filePos - runlength - 4);
iErr = FSWrite(refNum, &ioCount, &localRun.steps);
return iErr;
}
OSErr GetRunNumber(short refNum, long *outRuns)
{
OSErr iErr;
long ioCount;
if (refNum == 0)
return rfNumErr; /* 0 is invalid file number*/
iErr = SetFPos(refNum, fsFromStart, 0);
ioCount = sizeof(long);
iErr = FSRead(refNum, &ioCount, outRuns);
return iErr;
}
OSErr ReadLifeRun(short refNum, LifeRun *theRun, long whichRun)
{
OSErr iErr;
long ioCount;
unsigned long numRuns;
long index;
long logEOF;
long filePos;
long runlength;
if (refNum == 0)
return rfNumErr; /* 0 is invalid file number*/
iErr = GetEOF(refNum, &logEOF);
iErr = SetFPos(refNum, fsFromStart, 0);
ioCount = sizeof(long);
iErr = FSRead(refNum, &ioCount, &numRuns);
if (numRuns < whichRun)
return runAbsentErr;
if (whichRun == 0)
return runAbsentErr;
/* crawl to find logically the asked run*/
for (index = 0; index < whichRun; index++)
{
ioCount = sizeof(LifeRun);
iErr = FSRead(refNum, &ioCount, theRun);
if (iErr)
return iErr;
iErr = GetFPos(refNum, &filePos);
runlength = theRun->steps *
(sizeof(long) +
theRun->rbytes *
(theRun->worldSize.bottom - theRun->worldSize.top));
filePos += runlength;
if (filePos > logEOF)
return lifeFileCorruptErr;
iErr = SetFPos(refNum, fsFromStart, filePos);
}
return iErr;
}
OSErr ReadLifeWorld(short refNum, BitMapStep *lifeWorld,
long whichRun, long step)
{
OSErr iErr;
long ioCount;
long filePos;
long runlength;
LifeRun localRun;
iErr = ReadLifeRun(refNum, &localRun, whichRun);
if (iErr)
return iErr;
if ((step > localRun.steps) || (step < 1))
return stepAbsentErr;
/* we skipped the entire run with the call to ReadLifeRun
so we rewind the necessary length*/
runlength = (localRun.steps - step + 1) *
(sizeof(long) +
localRun.rbytes *
(localRun.worldSize.bottom - localRun.worldSize.top));
iErr = GetFPos(refNum, &filePos);
filePos -= runlength;
iErr = SetFPos(refNum, fsFromStart, filePos);
/* Now read the stepvalue */
ioCount = sizeof(long);
iErr = FSRead(refNum, &ioCount, &lifeWorld->stepvalue);
lifeWorld->cellsBM.rowBytes = localRun.rbytes;
lifeWorld->cellsBM.bounds = localRun.worldSize;
if ((localRun.worldSize.top != lifeWorld->cellsBM.bounds.top) ||
(localRun.worldSize.left != lifeWorld->cellsBM.bounds.left) ||
(localRun.worldSize.bottom != lifeWorld->cellsBM.bounds.bottom) ||
(localRun.worldSize.right != lifeWorld->cellsBM.bounds.right) ||
(localRun.rbytes != lifeWorld->cellsBM.rowBytes))
return badBitMapSizeErr;
/* And finally read the bitmap data */
ioCount = lifeWorld->cellsBM.rowBytes *
(lifeWorld->cellsBM.bounds.bottom - lifeWorld->cellsBM.bounds.top);
lifeWorld->cellsBM.baseAddr = NewPtr(ioCount);
if (lifeWorld->cellsBM.baseAddr == nil)
return memFullErr;
iErr = FSRead(refNum, &ioCount, lifeWorld->cellsBM.baseAddr);
return iErr;
}